﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using POC.Controls;
using System.Timers;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using ET.DBCommon.DAL;
using ET.DBCommon.Enum;
using ET.DBCommon.Model;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using ET_DbCommon.Model;

namespace RadioStationPOC.Views
{
    /// <summary>
    /// WirelessTrainUC.xaml 的交互逻辑
    /// </summary>
    public partial class WirelessTrainUC : UserControl, INotifyPropertyChanged
    {
        public WirelessTrainUC()
        {
            InitializeComponent();
        }

        Timer timer = new Timer();

        /// <summary>
        /// 自由考核模式下保存列车要播报的内容
        /// </summary>
        public Dictionary<int, string> VoiceContent { get; set; } = new Dictionary<int, string>();

        public List<string> waitTime = new List<string>();//第一步需要等待的呼叫

        //定义委托--Add by lukun
        public delegate void RoutedEventHandlers(object sender, RoutedEventArgs args);

        // 声明事件
        public event RoutedEventHandlers RouteHander;
        //定义委托,如果第一步选手操作，则终止后台等待--Add by lukun
        public delegate void WaitEventHandler();

        // 声明事件
        public event WaitEventHandler WaitHandle;

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.TrainList.Add(new TrainClass() { TrainGroupNumber = "通拨组", TrainTimeNumber = "  ", TrainStationArea = "  " });
            dgTrain.ItemsSource = this.TrainList;
            dgTalk.ItemsSource = this.TalkList;
            timer.Interval = 1000;
            timer.Elapsed += Timer_Elapsed;
            timer.Start();
        }

        private ObservableCollection<TrainClass> m_TrainList = new ObservableCollection<TrainClass>();

        public ObservableCollection<TrainClass> TrainList
        {
            get
            {
                return this.m_TrainList;
            }
            set
            {
                this.m_TrainList = value;
                this.OnPropertyChanged();
            }
        }

        private ObservableCollection<Talk> m_TalkList = new ObservableCollection<Talk>();

        public ObservableCollection<Talk> TalkList
        {
            get
            {
                return this.m_TalkList;
            }
            set
            {
                this.m_TalkList = value;
                this.OnPropertyChanged();
            }
        }

        #region INotifyPropertyChanged 接口实现
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string propName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        }
        #endregion
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                string strtrains = Encoding.UTF8.GetString(AccountServiceProvider.Get_Instance().Get_TrainInformation(Login.examId));
                if (string.IsNullOrWhiteSpace(strtrains)) return;

                var trainList = new List<TrainClass>();
                var trains = strtrains.Split('_');
                TrainClass trainClass = new TrainClass();
                trainClass.TrainGroupNumber = trains[0];
                trainClass.TrainTimeNumber = trains[1];
                trainClass.TrainStationArea = trains[2];
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    var allTrain = this.TrainList.ToList().FirstOrDefault(p => p.TrainGroupNumber == trainClass.TrainGroupNumber);
                    if (allTrain == null)
                    {
                        this.TrainList.Add(trainClass);
                    }
                    else
                    {
                        this.TrainList.ToList().FirstOrDefault(p => p.TrainGroupNumber == trainClass.TrainGroupNumber).TrainGroupNumber= trains[0];
                        this.TrainList.ToList().FirstOrDefault(p => p.TrainGroupNumber == trainClass.TrainGroupNumber).TrainTimeNumber = trains[1];
                        this.TrainList.ToList().FirstOrDefault(p => p.TrainGroupNumber == trainClass.TrainGroupNumber).TrainStationArea = trains[2];
                    }
                }));
                //str.Split('_').ToList().ForEach(
                //    p => trainList.Add(new TrainClass()
                //    {
                //        ID = 1,
                //        TrainGroupNumber = p.Split('_')[0],
                //        TrainTimeNumber = p.Split('_')[1],
                //        TrainStationArea = p.Split('_')[2]
                //    })); ;
                //trainList.Add(trainClass);
                //this.BindTrains(trainList);
            }
            catch (Exception ex)
            {
            }        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="trains"></param>
        private void BindTrains(List<TrainClass> trains)
        {
            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                for (int i = this.TrainList.Count - 1; i >= 0; i--)
                {
                    if (this.TrainList[i].TrainGroupNumber != "通拨组" && !trains.Exists(x => x.TrainGroupNumber == this.TrainList[i].TrainGroupNumber))
                        this.TrainList.Remove(this.TrainList[i]);
                }
                foreach (var train in trains)
                {
                    TrainClass trainClass = this.TrainList.FirstOrDefault(p => p.ID == train.ID);
                    if (trainClass == null)
                        this.TrainList.Add(train.Clone() as TrainClass);
                    else
                    {
                        trainClass.TrainStationArea = train.TrainStationArea;
                        trainClass.TrainTimeNumber = train.TrainTimeNumber;
                    }
                }
            }));
        }

        public void RefTalking()
        {
            var trains = this.TrainList.ToList().FindAll(p => MainWindow.CurMainWindow.CurStep.DeviceId.Split(',').Contains(p.ID.ToString()));
            foreach (var train in trains)
            {
                this.TalkList.Insert(0, new Talk() { Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), TrainGroupNumber = train.TrainGroupNumber, TrainTimeNumber = train.TrainTimeNumber });
            }
        }

        public void Display()
        {
            var trains = this.TrainList.ToList().FindAll(p => MainWindow.CurMainWindow.CurStep.DeviceId.Split(',').Contains(p.TrainGroupNumber.ToString()));
            if (MainWindow.CurMainWindow.CurStep.OperateId == (int)StepItemEnum.无线电台_接听)
            {
                trains.ForEach(p => p.CallStatus = TetraCallStatus.CallInRinging);
                Task.Run(new Action(() =>
                {
                    for (int i = 0; i < 26; i++)
                    {
                        this.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            trains.FindAll(p => p.CallStatus == TetraCallStatus.CallInRinging).ForEach(p => p.Background = i % 2 == 0 ? Brushes.White : Brushes.Orange);
                        }));
                        System.Threading.Thread.Sleep(200);
                    }
                }));
            }
        }

        public bool CallInWaiting(Exam_TestQuestion_Task_StepModel WaitStep)
        {
            var phone = this.TrainList.ToList().FindAll(p => p.CallStatus == TetraCallStatus.Talking && WaitStep.DeviceId.Split(',').Contains(p.ID.ToString()));
            if (phone.Count > 0)
            {
                phone.ForEach(p => p.IsWait = Visibility.Visible);
                Task.Run(() =>
                {
                    for (int i = 0; i < 26; i++)
                    {
                        this.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            phone.ForEach(p => p.Foreround = i % 2 == 0 ? Brushes.White : Brushes.Red);
                        }));

                        System.Threading.Thread.Sleep(200);
                    }
                });
                return true;
            }
            return false;
        }

        public void SendCommand(string txtCommand)
        {
            var allTrain = this.TrainList.ToList().FirstOrDefault(p => p.ID == 0);
            if (allTrain != null && allTrain.CallStatus == TetraCallStatus.Talking)
                this.CallOut(string.Join(",", this.TrainList.Where(p => p.TrainGroupNumber != "0").Select(p => p.TrainGroupNumber)), txtCommand);
            else
            {
                var train = this.TrainList.ToList().FindAll(p => p.CallStatus == TetraCallStatus.Talking);
                if (train.Count == 0) return;
                this.CallOut(string.Join(",", train.Select(p => p.TrainGroupNumber)), txtCommand);
            }
        }
       

        public void GiveUp()
        {
            var trains = this.TrainList.ToList().FindAll(p => p.CallStatus == TetraCallStatus.Talking);
            var log = this.CreateLog();
            log.DeviceId = string.Join(",", trains.Select(p => p.TrainGroupNumber));
            log.OperateId = (int)StepItemEnum.无线电台_放弃;

          //  OperationLogDAL.InsertOperationLog(log);
            //this.SwitchStep(trains.ToArray());
        }

        private void SwitchStep(string groupNumber = "", params TrainClass[] trains)
        {
            //trains.ToList().ForEach(p => p.CallStatus = TetraCallStatus.Free);
            var holding = trains.ToList().FindAll(p => p.IsWait == Visibility.Visible);
            if (holding.Count > 0)
            {
                holding.ForEach(p =>
                {
                    p.CallStatus = TetraCallStatus.Talking;
                    p.IsWait = Visibility.Collapsed;
                });
              //  MainWindow.CurMainWindow.CurStep = MainWindow.CurMainWindow.WaitStep;
                this.Answer(groupNumber, string.Join(",", holding.Select(p => p.TrainGroupNumber)));
            }
        }

        private void Answer(string devIDs, string groupNumber = "")
        {
            MainWindow.CurMainWindow.Ringing = false;
            this.RefTalking();
            var log = this.CreateLog();
            log.DeviceId = devIDs;
            if (groupNumber == "通拨组")
            {
                log.DeviceId = "201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230";
            }
            log.OperateId = (int)StepItemEnum.无线电台_接听;

           // OperationLogDAL.InsertOperationLog(log);
        }

        private OperatedLogModel CreateLog()
        {
            var log = new OperatedLogModel()
            {
                UserId = Login.userId,
                OperateId = MainWindow.CurMainWindow.CurStep.OperateId,
                OperatedTime = DateTime.Now,
                VirtualTime = DateTime.Parse(MainWindow.CurMainWindow.VirtualTime),
                DevicetypeId = (int)DeviceTypeEnum.列车,
                ExamId = Login.examId,
                //OperID = (int)StepItemEnum.调度电话_呼出,
                SysType = SystemType.ATS.ToString(),
            };
            return log;
        }
        public void ResetState()
        {
            this.TrainList.ToList().ForEach(p => p.CallStatus = TetraCallStatus.Free);
            var canvas = VisualHelper.FindVisualChildList<Canvas>(this.tabMulChoose);
            canvas.ForEach(p => { p.Children.Clear(); });
        }

        private Brush OpenBrush = new SolidColorBrush(Color.FromRgb(17, 49, 74));
        private Brush Backbrush = new SolidColorBrush(Color.FromRgb(10, 17, 54));
        private void TabControl_Click(object sender, RoutedEventArgs e)
        {
            var btn = e.OriginalSource as Button;
            var grid = VisualHelper.GetParentObject<Grid>(btn);
            var canvas = VisualHelper.FindVisualChild<Canvas>(grid);
            if (btn.Content.ToString() == "打开")
            {
                canvas.Background = Backbrush;
            }
            if (btn.Content is string)
            {
                btn.Content = btn.Content.ToString() == "打开" ? "关闭" : "打开";
                canvas.Background = canvas.Background == Backbrush ? OpenBrush : Backbrush;
            }
            else if (!(btn is ToolButton) && canvas.Background != OpenBrush)
            {
                var trainIDs = canvas.Children.OfType<ToolButton>().Select(p => (p.Tag as TrainClass).TrainGroupNumber);
                this.TrainList.ToList().FindAll(p => p.CallStatus == TetraCallStatus.Talking).ForEach(p => p.CallStatus = TetraCallStatus.Free);
                this.TrainList.ToList().FindAll(p => trainIDs.Contains(p.TrainGroupNumber)).ForEach(p => p.CallStatus = TetraCallStatus.Talking);
            }
        }

        private void DgTrain_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            var train = this.dgTrain.SelectedItem as TrainClass;
            if (train == null || train.TrainGroupNumber == "通拨组") return;
            var item = (this.tabMulChoose.SelectedItem as TabItem);
            var canvas = VisualHelper.FindVisualChild<Canvas>(item.Content as Grid);
            if (canvas.Background == OpenBrush && canvas.Children.OfType<ToolButton>().FirstOrDefault(p => p.MenuName == train.TrainGroupNumber) == null)
            {
                var appButton = new ToolButton()
                {
                    Width = 60,
                    ToolTip = train.TrainGroupNumber,
                    MenuName = train.TrainGroupNumber,
                    Tag = train,
                    ImageSource = new BitmapImage(new Uri("pack://application:,,,/POC;component/Images/列车.png", UriKind.RelativeOrAbsolute))
                };
                appButton.PreviewMouseRightButtonDown += AppButton_PreviewMouseRightButtonDown; ;
                Canvas.SetLeft(appButton, 20 + canvas.Children.Count * (appButton.Width + 20));
                Canvas.SetTop(appButton, 20);
                canvas.Children.Add(appButton);
            }
            RouteHander(sender, e);//触发事件--Add by lukun
        }

        private void AppButton_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            var train = sender as ToolButton;
            var canvas = train.Parent as Canvas;
            if (canvas.Background == OpenBrush)
                canvas.Children.Remove(train);
        }

        private void CallOut(string devId, string param = null)
        {
            var log = this.CreateLog();
            log.DeviceId = devId;
            if (log.DeviceId.Contains("通拨组"))
            {
                log.DeviceId = "201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230";
            }
            log.OperateId = (int)StepItemEnum.无线电台_呼出;
            log.AudioTile = MainWindow.CurMainWindow.CurAudioBuff;
            log.Parameters = param;
            log.VirtualTime = MainWindow.CurMainWindow.OperVirtualTime;
            if (this.waitTime.Contains(devId))
            {
                WaitHandle();
                this.waitTime.Clear();
            }
            Task.Run(() => {
                string JsonOperatedLog = JsonConvert.SerializeObject(log);
                AccountServiceProvider.Get_Instance().WriteOperatedLog(JsonOperatedLog);
            });
           // OperationLogDAL.InsertOperationLog(log);
        }
        private void CallOut_Click(object sender, RoutedEventArgs e)
        {
            var train = dgTrain.SelectedItem as TrainClass;
            if (train != null)
            {
                this.TrainList.ToList().FindAll(p => p.CallStatus == TetraCallStatus.Talking).ForEach(p => p.CallStatus = TetraCallStatus.Free);
                train.CallStatus = TetraCallStatus.Talking;
            }
        }

        private void Fast_Click(object sender, RoutedEventArgs e)
        {
            var train = dgTrain.SelectedItem as TrainClass;
            if (train != null)
            {
                train.CallStatus = TetraCallStatus.CallOutRinging;
                Task.Run(new Action(() =>
                {
                    for (int i = 0; i < 11; i++)
                    {
                        this.Dispatcher.BeginInvoke(new Action(() =>
                        {
                            train.Background = i % 2 == 0 ? Brushes.White : Brushes.Red;
                        }));
                        System.Threading.Thread.Sleep(200);
                    }
                    this.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        this.TrainList.ToList().FindAll(p => p.CallStatus == TetraCallStatus.Talking).ForEach(p => p.CallStatus = TetraCallStatus.Free);
                        train.CallStatus = TetraCallStatus.Talking;
                    }));
                }));
            }
        }

        private void DgTrain_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            var train = this.dgTrain.SelectedItem as TrainClass;
            if (train == null || train.TrainGroupNumber == "通拨组") return;
            var item = (this.tabMulChoose.SelectedItem as TabItem);
            var canvas = VisualHelper.FindVisualChild<Canvas>(item.Content as Grid);
            if (canvas.Background == OpenBrush && canvas.Children.OfType<ToolButton>().FirstOrDefault(p => p.MenuName == train.TrainGroupNumber) == null)
            {
                var appButton = new ToolButton()
                {
                    Width = 60,
                    ToolTip = train.TrainGroupNumber,
                    MenuName = train.TrainGroupNumber,
                    Tag = train,
                    ImageSource = new BitmapImage(new Uri("pack://application:,,,/RadioStationPOC;component/Images/列车.png", UriKind.RelativeOrAbsolute))
                };
                appButton.PreviewMouseRightButtonDown += AppButton_PreviewMouseRightButtonDown; ;
                Canvas.SetLeft(appButton, 20 + canvas.Children.Count * (appButton.Width + 20));
                Canvas.SetTop(appButton, 20);
                canvas.Children.Add(appButton);
            }
            RouteHander(sender, e);//触发事件--Add by lukun
        }

        private void DgTrain_Sorting(object sender, DataGridSortingEventArgs e)
        {

        }

        private void dgTrain_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var train = dgTrain.SelectedItem as TrainClass;
            if (train == null) return;
            if (train.CallStatus == TetraCallStatus.Talking)
                this.SwitchStep(train.TrainGroupNumber, train);
            if (train.CallStatus != TetraCallStatus.CallInRinging) return;
            this.TrainList.ToList().FindAll(p => p.CallStatus == TetraCallStatus.Talking).ForEach(p => p.CallStatus = TetraCallStatus.Free);
            train.CallStatus = TetraCallStatus.Talking;
            this.Answer(train.TrainGroupNumber.ToString());
        }
    }

    public class NotifyPropertyChanged : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged 接口实现
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string propName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        }
        #endregion
    }

    public class TrainClass : NotifyPropertyChanged, ICloneable
    {
        public int ID { get; set; }
        public string TrainGroupNumber { get; set; }

        private string m_TrainStationArea;
        public string TrainStationArea
        {
            get
            {
                return this.m_TrainStationArea;
            }
            set
            {
                this.m_TrainStationArea = value;
                this.OnPropertyChanged();
            }
        }

        private string m_TrainTimeNumber;
        public string TrainTimeNumber
        {
            get
            {
                return this.m_TrainTimeNumber;
            }
            set
            {
                this.m_TrainTimeNumber = value;
                this.OnPropertyChanged();
            }
        }

        private TetraCallStatus m_CallStatus = TetraCallStatus.Free;
        public TetraCallStatus CallStatus
        {
            get { return this.m_CallStatus; }
            set
            {
                this.m_CallStatus = value;
                if (this.m_CallStatus == TetraCallStatus.CallInRinging)
                    this.Background = Brushes.Orange;
                if (this.m_CallStatus == TetraCallStatus.Free)
                {
                    this.Background = Brushes.Transparent;
                    this.IsSelected = Visibility.Collapsed;
                }
                if (this.m_CallStatus == TetraCallStatus.Talking)
                {
                    this.Background = Brushes.DodgerBlue;
                    this.IsSelected = Visibility.Visible;
                    MainWindow.CurMainWindow.CurSystemType = SystemType.ATS;
                }
                if (this.m_CallStatus == TetraCallStatus.CallOutRinging)
                    this.Background = Brushes.Red;
            }
        }

        private Brush m_Background = Brushes.Transparent;
        /// <summary>
        /// 背景色
        /// </summary>
        public Brush Background
        {
            get
            {
                return this.m_Background;
            }
            set
            {
                this.m_Background = value;
                this.OnPropertyChanged();
            }
        }

        private Visibility m_IsSelected = Visibility.Collapsed;
        public Visibility IsSelected
        {
            get { return this.m_IsSelected; }
            set
            {
                this.m_IsSelected = value;
                this.OnPropertyChanged();
            }
        }

        private Brush m_Foreround = Brushes.White;
        /// <summary>
        /// 前景色
        /// </summary>
        public Brush Foreround
        {
            get
            {
                return this.m_Foreround;
            }
            set
            {
                this.m_Foreround = value;
                this.OnPropertyChanged();
            }
        }

        private Visibility m_IsWait = Visibility.Collapsed;
        public Visibility IsWait
        {
            get { return this.m_IsWait; }
            set
            {
                this.m_IsWait = value;
                this.OnPropertyChanged();
            }
        }

        public TrainClass()
        {

        }
        public TrainClass(Device model)
        {
            this.ID = model.DeviceId;
            this.TrainTimeNumber = model.DeviceName;
            this.IsSelected = Visibility.Collapsed;
        }
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }

    public class Talk
    {
        public string Time { get; set; }
        public string TrainGroupNumber { get; set; }
        public string TrainTimeNumber { get; set; }
    }

    public enum TetraCallStatus
    {
        Free = 1,
        CallInRinging,
        Talking,
        CallOutRinging
    }
}
